home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
GLR
/
glrduckpond.c++
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
10KB
|
425 lines
/* Copyright (c) Silicon Graphics, 1996. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
/* CC -o glrduckpond glrduckpond.c++ -lGLR -lglut -lInventor -lGL -lGLU -lXmu -lXext -lX11 -lm */
#include <stdio.h>
#include <unistd.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glr.h>
#include <GL/glut.h>
#include <Inventor/SoDB.h>
#include <Inventor/SoInput.h>
#include <Inventor/SbViewportRegion.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoRotationXYZ.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoTranslation.h>
#include <Inventor/engines/SoElapsedTime.h>
#include <Inventor/engines/SoGate.h>
#include <Inventor/nodes/SoComplexity.h>
int first = 1;
int quality = 1;
int W = 300, H = 300;
int timeout = 5000, waitTime = 250;
int spinning = 0;
int win;
GLrSession session;
GLrCanvasType canvasType;
GLrCanvas canvas;
GLubyte *image = NULL;
int sceneChanged = 1;
SoSeparator *localDuck, *remoteDuck, *root;
SoRotationXYZ *duckRotXYZ, *localRot, *remoteRot;
float angle = 0.0;
void
reshape(int w, int h)
{
float areaChange;
areaChange = ((float) w*h)/((float) W*H) + 0.20; /* areaChange has 20% increase slop */
timeout = (int)((float) timeout * areaChange);
sceneChanged = 1;
glViewport(0, 0, w, h);
W = w;
H = h;
if (image)
free(image);
image = (GLubyte *) malloc(W * H * 3);
}
void
renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SbViewportRegion myViewport(W, H);
SoGLRenderAction myRenderAction(myViewport);
myRenderAction.apply(root);
}
void
prepImageBlit(void)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, W, 0, H);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
}
void
postImageBlit(void)
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
}
void
output(int x, int y, char *string)
{
int len, i;
glRasterPos2i(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, string[i]);
}
}
void
redraw(void)
{
int status, attempt, expired;
char message[40];
if(quality && !first) {
prepImageBlit();
if(sceneChanged) {
attempt = 0;
expired = 0;
glDrawBuffer(GL_FRONT);
glDisable(GL_LIGHTING);
do {
if(waitTime > 10) {
attempt++;
if(expired > 0) {
glColor3f(1.0, 0.0, 0.0);
} else {
glColor3f(1.0, 1.0, 1.0);
}
sprintf(message, "Interval: %-8d", timeout);
output(10, H - 10 - 10*attempt, message);
attempt++;
}
status = glrBeginRenderInterval(canvas, W, H, timeout, waitTime);
if(status == 0) {
waitTime = 10;
glutSetWindow(win);
glDrawBuffer(GL_BACK);
postImageBlit();
goto localRender;
}
waitTime = 250;
root = remoteDuck;
renderScene();
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
status = glrEndRenderInterval(canvas, &timeout);
if(status == 0) {
glutSetWindow(win);
expired++;
}
timeout = (int)((float) timeout * 1.4);
} while(!status);
sceneChanged = 0;
}
/* XXX Careful! Versions of GLUT through 2.2.1 tried to cache the
current window/context binding to avoid unnecessary glXMakeCurrent
calls, but using GLR and GLUT together violates the assumption
that only GLUT called glXMakeCurrent. */
glutSetWindow(win);
glDrawBuffer(GL_BACK);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glRasterPos2i(0, 0);
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
postImageBlit();
glFinish();
glutSwapBuffers();
} else {
localRender:
root = localDuck;
renderScene();
glFinish();
glutSwapBuffers();
if(first) {
first = 0;
glutPostRedisplay();
}
}
}
int ms_attrs[] =
{GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, GLR_SAMPLES_SGIS, 4, 0};
int attrs[] =
{GLR_RGBA, GLR_RED_SIZE, 1, GLR_GREEN_SIZE, 1, GLR_BLUE_SIZE, 1, GLR_DEPTH_SIZE, 16, 0};
SoSeparator*
duckScene(float complex)
{
root = new SoSeparator;
root->ref();
SoComplexity *complexity = new SoComplexity;
complexity->value = complex;
root->addChild(complexity);
// Add a camera and light
SoPerspectiveCamera *myCamera = new SoPerspectiveCamera;
myCamera->position.setValue(0., -4., 8.0);
myCamera->heightAngle = M_PI/2.5;
myCamera->nearDistance = 1.0;
myCamera->farDistance = 15.0;
root->addChild(myCamera);
root->addChild(new SoDirectionalLight);
// Rotate scene slightly to get better view
SoRotationXYZ *globalRotXYZ = new SoRotationXYZ;
globalRotXYZ->axis = SoRotationXYZ::X;
globalRotXYZ->angle = M_PI/9;
root->addChild(globalRotXYZ);
// Pond group
SoSeparator *pond = new SoSeparator;
root->addChild(pond);
SoMaterial *cylMaterial = new SoMaterial;
cylMaterial->diffuseColor.setValue(0., 0.3, 0.8);
pond->addChild(cylMaterial);
SoTranslation *cylTranslation = new SoTranslation;
cylTranslation->translation.setValue(0., -6.725, 0.);
pond->addChild(cylTranslation);
SoCylinder *myCylinder = new SoCylinder;
myCylinder->radius.setValue(4.0);
myCylinder->height.setValue(0.5);
pond->addChild(myCylinder);
// Duck group
SoSeparator *duck = new SoSeparator;
root->addChild(duck);
// Read the duck object from a file and add to the group
SoInput myInput;
if (!myInput.openFile("duck.iv")) {
if (!myInput.openFile("/usr/share/src/Inventor/examples/data/duck.iv")) {
return NULL;
}
}
SoSeparator *duckObject = SoDB::readAll(&myInput);
if (duckObject == NULL) return NULL;
// Set up the duck transformations
duckRotXYZ = new SoRotationXYZ;
duck->addChild(duckRotXYZ);
duckRotXYZ->angle = angle;
duckRotXYZ->axis = SoRotationXYZ::Y; // rotate about Y axis
SoTransform *initialTransform = new SoTransform;
initialTransform->translation.setValue(0., 0., 3.);
initialTransform->scaleFactor.setValue(6., 6., 6.);
duck->addChild(initialTransform);
duck->addChild(duckObject);
return root;
}
void
updateModels(void)
{
sceneChanged = 1;
localRot->angle = angle;
remoteRot->angle = angle;
glutPostRedisplay();
}
void
animate(void)
{
angle += 0.1;
updateModels();
}
void
setAnimation(int enable)
{
if(enable) {
quality = 0;
spinning = 1;
glutIdleFunc(animate);
} else {
sceneChanged = 1;
quality = 1;
spinning = 0;
glutIdleFunc(NULL);
sceneChanged = 1;
glutPostRedisplay();
}
}
/* ARGSUSED */
void
keyboard(unsigned char ch, int x, int y)
{
if(ch == ' ') {
setAnimation(0);
animate();
}
}
void
menuSelect(int item)
{
switch(item) {
case 1:
animate();
break;
case 2:
if(!spinning) {
setAnimation(1);
} else {
setAnimation(0);
}
break;
}
}
void
vis(int visible)
{
if (visible == GLUT_VISIBLE) {
if (spinning)
glutIdleFunc(animate);
} else {
if (spinning)
glutIdleFunc(NULL);
}
}
void
gfxinit(void)
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.132, 0.542, 0.132, 1.0);
}
int moving = 0;
int begin;
/* ARGSUSED */
void
mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
setAnimation(0);
moving = 1;
begin = x;
quality = 0;
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
moving = 0;
quality = 1;
sceneChanged = 1;
glutPostRedisplay();
}
}
/* ARGSUSED */
void
motion(int x, int y)
{
if (moving) {
angle = angle + .01 * (x - begin);
begin = x;
updateModels();
}
}
void
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
SoDB::init();
localDuck = duckScene(0.4);
if(localDuck == NULL) {
fprintf(stderr, "couldn't read IV file\n");
exit(1);
}
localRot = duckRotXYZ;
remoteDuck = duckScene(0.9);
if(remoteDuck == NULL) {
fprintf(stderr, "couldn't read IV file\n");
exit(1);
}
remoteRot = duckRotXYZ;
session = glrOpenSession(NULL);
if (session == NULL) {
fprintf(stderr, "couldn't get GLR session\n");
exit(1);
}
canvasType = glrGetCanvasType(session, ms_attrs);
if (canvasType == NULL) {
canvasType = glrGetCanvasType(session, attrs);
if (canvasType == NULL) {
fprintf(stderr, "couldn't get usable canvas type\n");
exit(1);
}
}
canvas = glrCreateCanvas(canvasType, NULL);
glrEstablishRenderState(canvas);
gfxinit();
glutInitWindowSize(W, H);
win = glutCreateWindow("GLUT Inventor Multisampling");
glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutCreateMenu(menuSelect);
glutAddMenuEntry("Step", 1);
glutAddMenuEntry("Toggle animation", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutVisibilityFunc(vis);
gfxinit();
glutMainLoop();
}